#include "scoundrel.h"
#include "ui_scoundrel.h"
#include "SpellEffect.h"
#include "Ability.h"
#include "Rotation.h"
#include "RatingConvert.h"
#include <fstream>
#include "time.h"
#include "cmath"

Scoundrel::Scoundrel(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::Scoundrel)
{
    ui->setupUi(this);
    string filename = "Scoundrel_stats.txt";
    ifstream fin (filename.c_str());
    if(fin.good()){
        Load_Stats();}
    updateStatBoxes();

    //    srand( time(NULL));

}

Scoundrel::~Scoundrel()
{
    delete ui;
}

enum STATS {
    AIM = 0, CUNNING, STRENGTH, WILLPOWER = 3,
    CRIT, SURGE, ALACRITY , POWER , ACCURACY = 8,
    DEFENSE, SHIELD, ABSORB, ARMOR = 12,
    LEVEL, MH_ACC, OH_ACC, ENEMY_LEVEL, ENEMY_ARMOR= 17,
    SPEED,  MH_MAX, MH_MIN, OH_MAX , OH_MIN =22,
    TECH_CRIT_CHANCE , TECH_CRIT_SIZE, TECH_BONUS_HEALING, TECH_BONUS_DAMAGE = 26,
    RANGED_CRIT_CHANCE , RANGED_CRIT_SIZE, RANGED_BONUS_DAMAGE = 29,
    FORCE_CRIT_CHANCE , FORCE_CRIT_SIZE, FORCE_BONUS_HEALING, FORCE_BONUS_DAMAGE = 33,
    MELEE_CRIT_CHANCE , MELEE_CRIT_SIZE, MELEE_BONUS_DAMAGE = 36,
    TECH_POWER, FORCE_POWER = 38
};

std::vector <double> scStats(39,0);
QString scRotation;
int UWM_count;
int EMP_count;
int SRMP_cast_count;
int DS_count;
int KPa_count;
double regenTime;

void Scoundrel::setStats()
{
    int accBuff = 0;
    int critBuff = 2*(ui->skillBox_2->value());
    if(ui->smugglerCheckBox->isChecked()) critBuff += 5;
    int techSurgeBuff = 0;
    int alacBuff = 2*(ui->skillBox_6->value());

    int cunning = ui->primaryBox->value();
    if(ui->consularCheckBox->isChecked()) cunning *= 1.05;

    scStats.at(CUNNING) = cunning;
    //scStats.at(SECONDARY) = ui->secondaryBox->value();
    scStats.at(CRIT)= ui->critBox->value();
    scStats.at(SURGE)= ui->surgeBox->value();
    scStats.at(POWER)= ui->powerBox->value();
    scStats.at(TECH_POWER) = ui->techBox->value();
    scStats.at(ALACRITY)= ui->alacBox->value();
    scStats.at(LEVEL)= ui->levelBox->value();

    scStats.at(ACCURACY) = ui->accBox->value();
    scStats.at(MH_MAX) = ui->MHmaxBox->value();
    scStats.at(MH_MIN) = ui->MHminBox->value();
    scStats.at(ENEMY_LEVEL) = ui->enemyLevelBox->value();
    scStats.at(ENEMY_ARMOR) = ui->enemyArmorBox->value();

    scStats.at(TECH_CRIT_CHANCE) = ( TechCritChance(scStats, critBuff, false));
    scStats.at(TECH_CRIT_SIZE) = ( TechCritSize(scStats, techSurgeBuff));
    scStats.at(SPEED) =( Speed(scStats, alacBuff));
    scStats.at(TECH_BONUS_HEALING) = (TechBonusHealing((scStats.at(POWER)+scStats.at(TECH_POWER)), scStats.at(CUNNING)));
    scStats.at(MH_ACC) = (MH_Accuracy(scStats, accBuff));
    scStats.at(TECH_BONUS_DAMAGE) = TechBonusDamage(scStats, false);
    scStats.at(RANGED_CRIT_CHANCE) = ( RangedCritChance(scStats, critBuff, true));
    scStats.at(RANGED_CRIT_SIZE) = ( RangedCritSize(scStats, 0));
    scStats.at(RANGED_BONUS_DAMAGE) = RangedBonusDamage(scStats, true);

}

vector <double> Scoundrel::calculateStats(vector <double> &stats2){
    int accBuff = 0;
    int critBuff = 2*(ui->skillBox_2->value());
    if(ui->smugglerCheckBox->isChecked()) critBuff += 5;
    int techSurgeBuff = 0;
    int rangedSurgeBuff = 0;
    int alacBuff = 2*(ui->skillBox_6->value());


    stats2.at(TECH_CRIT_CHANCE) = ( TechCritChance(stats2, critBuff, false));
    stats2.at(TECH_CRIT_SIZE) = ( TechCritSize(stats2, techSurgeBuff));
    stats2.at(SPEED) =( Speed(stats2, alacBuff));
    stats2.at(TECH_BONUS_HEALING) = (TechBonusHealing((stats2.at(POWER)+stats2.at(TECH_POWER)) ,stats2.at(CUNNING)));
    stats2.at(MH_ACC) = (MH_Accuracy(stats2, accBuff));
    stats2.at(TECH_BONUS_DAMAGE) = TechBonusDamage(stats2, false);
    stats2.at(RANGED_CRIT_CHANCE) = ( RangedCritChance(stats2, critBuff, true));
    stats2.at(RANGED_CRIT_SIZE) = ( RangedCritSize(stats2, rangedSurgeBuff));
    stats2.at(RANGED_BONUS_DAMAGE) = RangedBonusDamage(stats2, true);
    return stats2;
}

void Scoundrel::updateStatBoxes()
{
    setStats();
    ui->techCritChanceLabel->setText(QString::number(scStats.at(TECH_CRIT_CHANCE)));
    ui->techCritSizeLabel->setText(QString::number(scStats.at(TECH_CRIT_SIZE)));
    ui->rangedCritChanceLabel->setText(QString::number(scStats.at(RANGED_CRIT_CHANCE)));
    ui->rangedCritSizeLabel->setText(QString::number(scStats.at(RANGED_CRIT_SIZE)));
    ui->speedLabel->setText(QString::number(100*(1-scStats.at(SPEED))));
    ui->bonusHealingLabel->setText(QString::number(scStats.at(TECH_BONUS_HEALING)));
    ui->MHaccLabel->setText(QString::number(scStats.at(MH_ACC)));
    ui->techBonusDamageLabel->setText(QString::number(scStats.at(TECH_BONUS_DAMAGE)));
    ui->rangedBonusDamageLabel->setText(QString::number(scStats.at(RANGED_BONUS_DAMAGE)));

    ui->accBox->setEnabled(true);
    ui->accBox_2->setEnabled(true);
    ui->accBox_3->setEnabled(true);
    ui->accuracyButton->setEnabled(true);
    ui->accLabel->setEnabled(true);
    ui->accLabel_2->setEnabled(true);
    ui->accLabel_3->setEnabled(true);
    ui->accWeightLabel->setEnabled(true);
    ui->MHaccLabel->setEnabled(true);
    ui->MHaccLabel_2->setEnabled(true);
    ui->OHaccLabel->setEnabled(true);
    ui->OHaccLabel_2->setEnabled(true);
    ui->MHmaxBox->setEnabled(true);
    ui->MHmaxLabel->setEnabled(true);
    ui->MHminBox->setEnabled(true);
    ui->MHminLabel->setEnabled(true);
    ui->OHmaxBox->setEnabled(true);
    ui->OHmaxLabel->setEnabled(true);
    ui->OHminBox->setEnabled(true);
    ui->OHminLabel->setEnabled(true);

    ui->enemyArmorBox->setEnabled(true);
    ui->enemyArmorLabel->setEnabled(true);
    ui->enemyLevelBox->setEnabled(true);
    ui->enemyLevelLabel->setEnabled(true);
    ui->missChanceLabel->setEnabled(true);
    ui->missChanceLabel_2->setEnabled(true);
    ui->accWeightLabel_2->setEnabled(true);
    ui->enemyDRLabel->setEnabled(true);
    ui->enemyDRLabel_2->setEnabled(true);

    ui->set2pcLabel->setText("Reduces the Energy cost of Kolto Cloud by 4");
    ui->set4pcLabel->setText("Increases the critical chance of Kolto Pack by 15%");

    if(ui->tree1->isChecked()){
        ui->accBox->setEnabled(false);
        ui->accBox_2->setEnabled(false);
        ui->accBox_3->setEnabled(false);
        ui->accuracyButton->setEnabled(false);
        ui->accLabel->setEnabled(false);
        ui->accLabel_2->setEnabled(false);
        ui->accLabel_3->setEnabled(false);
        ui->accWeightLabel->setEnabled(false);
        ui->MHaccLabel->setEnabled(false);
        ui->MHaccLabel_2->setEnabled(false);
        ui->OHaccLabel->setEnabled(false);
        ui->OHaccLabel_2->setEnabled(false);
        ui->MHmaxBox->setEnabled(false);
        ui->MHmaxLabel->setEnabled(false);
        ui->MHminBox->setEnabled(false);
        ui->MHminLabel->setEnabled(false);
        ui->OHmaxBox->setEnabled(false);
        ui->OHmaxLabel->setEnabled(false);
        ui->OHminBox->setEnabled(false);
        ui->OHminLabel->setEnabled(false);

        ui->enemyArmorBox->setEnabled(false);
        ui->enemyArmorLabel->setEnabled(false);
        ui->enemyLevelBox->setEnabled(false);
        ui->enemyLevelLabel->setEnabled(false);
        ui->missChanceLabel->setEnabled(false);
        ui->missChanceLabel_2->setEnabled(false);
        ui->accWeightLabel_2->setEnabled(false);
        ui->enemyDRLabel->setEnabled(false);
        ui->enemyDRLabel_2->setEnabled(false);

    }
}


void Scoundrel::on_calcWeightButton_clicked()
{
    updateStatBoxes();
    getWeights();

}
void Scoundrel::getWeights(){
    //copy stats for modification
    setStats();
    vector <double> stats2 = scStats;
    double baseHPS, cunHPS, powerHPS, critHPS, surgeHPS, alacHPS =0, refStat=1;

    int numRotations = ui->optionBox_2->value();
    double statBuff = 1+0.03*(ui->skillBox_1->value());
    std::vector <double> weights(8,0);
    for(int m=0;m<6;m++){
        stats2 = scStats;
        switch(m){
        case 0:
            break;
        case 1:
            stats2.at(CUNNING)+= (1*statBuff);
            break;
        case 2:
            stats2.at(POWER)+=1;
            break;
        case 3:
            stats2.at(CRIT)+=1;
            break;
        case 4:
            stats2.at(SURGE)+=1;
            break;
        case 5:
            stats2.at(ALACRITY)+=1;
            break;
            //        case 6:
            //            stats2.at(SECONDARY)+=1;
            break;
        default:
            break;
        }
        stats2 = calculateStats(stats2);
        srand(1);
        for(int n=0;n<numRotations;n++){
            if(ui->burstButton->isChecked()){
                double numCasts = ui->numCasts->value();
                weights.at(m) += sawbonesBurst(numCasts, stats2);
            }else{
                if(ui->fixedTimeButton->isChecked()){
                    double numCasts = ui->numCasts->value();
                    weights.at(m)+=sawbonesRotation(numCasts, stats2);
                }else{
                    int numCasts = ui->numCasts->value();
                    weights.at(m)+=sawbonesRotation(numCasts, stats2);
                }
            }
        }

    }
    baseHPS = (weights.at(0)/numRotations);
    cunHPS = (weights.at(1)/numRotations) -baseHPS;
    powerHPS = (weights.at(2)/numRotations) -baseHPS;
    critHPS = (weights.at(3)/numRotations) -baseHPS;
    surgeHPS = (weights.at(4)/numRotations) -baseHPS;
    alacHPS = (weights.at(5)/numRotations) -baseHPS;

    if(ui->powerButton->isChecked())refStat = powerHPS;
    if(ui->aimButton->isChecked())refStat = cunHPS;
    if(ui->critButton->isChecked())refStat = critHPS;
    if(ui->surgeButton->isChecked())refStat = surgeHPS;
    if(ui->alacrityButton->isChecked())refStat = alacHPS;
    //if(ui->accuracyButton->isChecked())refStat = accuracyDPS;

    double powerWeight = powerHPS/refStat;
    double cunWeight = cunHPS/refStat;
    //double cunningWeight = cunningHPS/refStat;
    double critWeight = critHPS/refStat;
    double surgeWeight = surgeHPS/refStat;
    double alacWeight = alacHPS/refStat;

    ui->critWeightLabel->setText(QString::number(critWeight));
    ui->surgeWeightLabel->setText(QString::number(surgeWeight));
    ui->alacWeightLabel->setText(QString::number(alacWeight));
    ui->powerWeightLabel->setText(QString::number(powerWeight));
    ui->primaryWeightLabel->setText(QString::number(cunWeight));
    //ui->secondaryWeightLabel->setText(QString::number(cunningWeight));
}

void Scoundrel::on_calcHPSButton_clicked()
{
    srand(1);
    updateStatBoxes();
    ui->castView->clear();
    ui->countView->clear();
    int numRotations = ui->optionBox_2->value();
    double HPS = 0;
    setStats();
    double rotationTime = ui->numCasts->value();
    int numCasts = ui->numCasts->value();
    for(int n=0;n<numRotations;n++){
        if(ui->burstButton->isChecked()){
            HPS += sawbonesBurst(rotationTime, scStats);
        }else{
            if(ui->fixedTimeButton->isChecked()){
                HPS += sawbonesRotation(rotationTime, scStats);
            }else{
                HPS += sawbonesRotation(numCasts, scStats);
            }
        }
    }
    HPS = HPS/numRotations;
    QString countString;
    if(ui->burstButton->isChecked()){
        countString = "UWM casts: " + QString::number(UWM_count)+"\nKPa casts: " + QString::number(KPa_count)
                + "\nDS casts: " + QString::number(DS_count)+"\nTotal casts: " + QString::number(UWM_count+KPa_count+DS_count);
    }else{
        countString = "UWM casts: " + QString::number(UWM_count)+"\nEMP casts: " + QString::number(EMP_count)
                +"\nSRMP casts: " + QString::number(SRMP_cast_count)+ "\nDS casts: " + QString::number(DS_count)
                +"\nTotal casts: " + QString::number(UWM_count+SRMP_cast_count+EMP_count+DS_count);
    }
    ui->countView->insertPlainText(countString);
    ui->HPSlabel->setText(QString::number(HPS));
    ui->castView->insertPlainText(scRotation);
}

void Scoundrel::on_computeAlacrityButton_clicked()
{
    ui->castView->clear();
    ui->countView->clear();
    setStats();
    vector <double> stats2=scStats;
    QString alacOutput;
    if(ui->burstButton->isChecked()){
        alacOutput = "Haste%, UWM Casts, KPa Casts, DS Casts, Total Casts, HPS\n\n";
    }else{
        alacOutput = "Haste%, UWM Casts, EMP Casts, DS Casts, Total Casts, HPS\n\n";
    }
    double rotationTime = ui->numCasts->value();
    int numCasts = ui->numCasts->value();
    double HPS;
    int numRotations = ui->optionBox_2->value();
    for(double m=0.0;m<39.5;m+=0.5){
        stats2.at(SPEED)=1-(m/100);
        HPS = 0;
        srand(1);
        for(int n=0;n<numRotations;n++){
            if(ui->burstButton->isChecked()){
                HPS += sawbonesBurst(rotationTime, stats2);
            }else{
                if(ui->fixedTimeButton->isChecked()){
                    HPS += sawbonesRotation(rotationTime, stats2);
                }else{
                    HPS += sawbonesRotation(numCasts, stats2);
                }
            }
        }
        HPS = HPS/numRotations;
        if(ui->burstButton->isChecked()){
            alacOutput += QString::number(m) +" , " + QString::number(UWM_count) +" ,  " + QString::number(KPa_count)
                    +" , " + QString::number(DS_count)+" , " + QString::number(SRMP_cast_count + UWM_count + EMP_count + DS_count)
                    +" , " + QString::number(HPS) +"\n";
        }else{
            alacOutput += QString::number(m) +" , " + QString::number(UWM_count) +" ,  " + QString::number(EMP_count)
                    +" , " + QString::number(DS_count)+" , " + QString::number(SRMP_cast_count + UWM_count + EMP_count + DS_count)
                    +" , " + QString::number(HPS) +"\n";
        }
    }
    ui->countView->insertPlainText(alacOutput);
}

void Scoundrel::compareUpgrades(){
    setStats();
    vector <double> stats1 = scStats;
    vector <double> stats2 = scStats;
    double baseHPS = 0, upg1HPS = 0, upg2HPS = 0;
    double rotationTime = ui->numCasts->value();
    int numCasts = ui->numCasts->value();

    int numRotations = ui->optionBox_2->value();
    double statBuff = 1 + 0.03*(ui->skillBox_1->value());
    if(ui->consularCheckBox->isChecked()) statBuff += 0.05;
    srand(1);
    for(int n=0;n<numRotations;n++){
        if(ui->burstButton->isChecked()){
            baseHPS += sawbonesBurst(rotationTime, scStats);
        }else{
            if(ui->fixedTimeButton->isChecked()){
                baseHPS += sawbonesRotation(rotationTime, scStats);
            }else{
                baseHPS += sawbonesRotation(numCasts, scStats);
            }
        }
    }
    baseHPS = baseHPS/numRotations;

    //populate upgrade 1
    stats1.at(CUNNING) += (ui->primaryBox_2->value())*statBuff;
    //stats1.at(SECONDARY) += ui->secondaryBox_2->value();
    stats1.at(CRIT) += ui->critBox_2->value();
    stats1.at(SURGE) += ui->surgeBox_2->value();
    stats1.at(POWER) += ui->powerBox_2->value() + ui->techBox_2->value();
    stats1.at(ALACRITY) += ui->alacBox_2->value();

    srand(1);
    stats1 = calculateStats(stats1);
    for(int n=0;n<numRotations;n++){
        if(ui->burstButton->isChecked()){
            upg1HPS += sawbonesBurst(rotationTime, stats1);
        }else{
            if(ui->fixedTimeButton->isChecked()){
                upg1HPS += sawbonesRotation(rotationTime, stats1);
            }else{
                upg1HPS += sawbonesRotation(numCasts, stats1);
            }
        }
    }
    upg1HPS = upg1HPS/numRotations;
    //populate upgrade 2
    stats2.at(CUNNING) += (ui->primaryBox_3->value())*statBuff;
    //stats2.at(SECONDARY) += ui->secondaryBox_3->value();
    stats2.at(CRIT) += ui->critBox_3->value();
    stats2.at(SURGE) += ui->surgeBox_3->value();
    stats2.at(POWER) += ui->powerBox_3->value() + ui->techBox_2->value();
    stats2.at(ALACRITY) += ui->alacBox_3->value();
    srand(1);
    stats2 = calculateStats(stats2);
    for(int n=0;n<numRotations;n++){
        if(ui->burstButton->isChecked()){
            upg2HPS += sawbonesBurst(rotationTime, stats2);
        }else{
            if(ui->fixedTimeButton->isChecked()){
                upg2HPS += sawbonesRotation(rotationTime, stats2);
            }else{
                upg2HPS += sawbonesRotation(numCasts, stats2);
            }
        }
    }
    upg2HPS = upg2HPS/numRotations;
    upg1HPS -= baseHPS;
    upg2HPS -= baseHPS;

    ui->HPSlabel_2->setText(QString::number(upg1HPS));
    ui->HPSlabel_3->setText(QString::number(upg2HPS));

    if(upg1HPS == upg2HPS) ui->upg3Label->setText("No difference");
    if(upg1HPS > upg2HPS) ui->upg3Label->setText("Use Item 1");
    if(upg1HPS < upg2HPS) ui->upg3Label->setText("Use Item 2");
}

void Scoundrel::on_upgradeButton_clicked()
{
    compareUpgrades();
    updateStatBoxes();
}

double Scoundrel::sawbonesRotation(int numCasts, vector <double> &stats){
    UWM_count = 0;
    EMP_count = 0;
    SRMP_cast_count = 0;
    DS_count = 0;

    scRotation = "";
    //Abilities
    //Sc: UWM -> EMP (Kolto Injection -> Surgical Probe)
    //Underworld Medicine
    Ability UWM(2.0, 25, false, 2.72, 0.116, 0.156);
    //Emergency Med Probe
    Ability EMP(1.5, 0, true, 1.37, 0.038, 0.098);
    //SRMP (kolto probe)
    Ability SRMP(1.5, 15, true, 0.336, 0.0168, 0.0168, 1, 0.0);//ticks set to one, as each tick will be added on its own.
    //Diagnostic Scan
    Ability DS(3,0,false,0.334,0,0,3,0.0);
    //Pugnacity (Stim Boost) consumes 1 UH/TA but needs to be kept up
    //consumes 1 UH, lasts 45s, adds 1 Energy per second
    //Cool Head (Adrenaline Probe) used if energy drops below 20.
    //restore 50 + 8 per skill point.

    double bonusHealing = stats.at(TECH_BONUS_HEALING);
    double critChance = stats.at(TECH_CRIT_CHANCE);
    double critSize = stats.at(TECH_CRIT_SIZE);
    double speed = stats.at(SPEED);

    double knight_buff = 1;
    if (ui->knightCheckBox->isChecked()) knight_buff = 1.05;
    knight_buff *= (1+0.01*(ui->skillBox_9->value())); //add Survivor's Scars into the healing multiplier.
    //Establish cooldowns and timers
    //UH stacks
    double hot_buff = 1+0.05*(ui->skillBox_5->value());
    double EMP_buff = 1+0.03*(ui->skillBox_5->value());
    double CH_use = ui->optionBox_3->value();
    double pug_use = 2; //create an option for this?
    double Energy = 100;
    int UH = 0;
    double UH_duration = 0; //lasts 10 seconds
    double CH_CD = 0; //2 minute cooldown
    double CH_CD_duration = 120;
    int CH_restore = 50+8*(ui->skillBox_7->value()); //amount Cool Head restore, including Keep Cool skill
    double pugRemaining = 0; //time left on pugnacity
    double pugTime = 0;
    regenTime = 0;
    double SRMP_ICD = 9 - (1.5*(ui->skillBox_8->value()-1)); // how often SRMP can grant UH
    double SRMP_time = 0;
    double SRMP_count = 0;
    double SRMP_last_tick = 0;
    double UWM_limit = ui->optionBox_1->value();
    //SRMP UH proc chance: 30%
    double tTime = 0;
    double tHeal = 0;
    double eTime = 0;
    double eHeal = 0;
    double rEnergy = 0;
    double tEnergy = 0;
    Ability abil;
    string ability;
    bool proc;

    //Opener
    //UWM
    tHeal = UWM.getHealing(bonusHealing)*knight_buff*1.03;
    tHeal = tHeal * ((1 - critChance / 100)+(1+0.1*(ui->skillBox_4->value()) + critSize / 100)*(critChance / 100));
    tTime = UWM.getCastTime(speed);
    tEnergy = UWM.getAmmo();
    ability = "UWM";
    abil = UWM;
    UWM_count++;
    eHeal += tHeal;
    eTime += tTime;
    rEnergy = getEnergyRegened(Energy, abil, eTime, regenTime, pugTime, pugRemaining);
    Energy -= (tEnergy - rEnergy);
    Energy = max(min(Energy, 100.0),0.0);
    UH++;
    UH_duration=10;
    scRotation += "UWM, " + QString::number(Energy) + " , "+ QString::number(tHeal) + " , "+ QString::number(eTime) + " , " +QString::number(UH) +"\n";
    tHeal = 0;
    //pug
    pugRemaining = 45;
    pugTime = eTime;
    UH--;
    scRotation += "Pugnacity used\n";
    //UWM
    tHeal = UWM.getHealing(bonusHealing)*knight_buff*1.03;
    tHeal = tHeal * ((1 - critChance / 100)+(1+0.1*(ui->skillBox_4->value()) + critSize / 100)*(critChance / 100));
    tTime = UWM.getCastTime(speed);
    tEnergy = UWM.getAmmo();
    ability = "UWM";
    abil = UWM;
    UWM_count++;
    eHeal += tHeal;
    eTime += tTime;
    rEnergy = getEnergyRegened(Energy, abil, eTime, regenTime, pugTime, pugRemaining);
    Energy -= (tEnergy - rEnergy);
    Energy = max(min(Energy, 100.0),0.0);
    UH++;
    UH_duration=10;
    scRotation += "UWM, " + QString::number(Energy) + " , "+ QString::number(tHeal) + " , "+ QString::number(eTime) + " , " +QString::number(UH) +"\n";
    tHeal = 0;
    //start loop
    for(int n=0;n<(numCasts-2);n++){
        if((Energy<=CH_use) && (CH_CD == 0)){
            Energy += CH_restore;
            CH_CD = CH_CD_duration;
        }
        if(pugRemaining<=1.5 && UH>(pug_use-1))
        {
            pugRemaining = 45;
            pugTime = eTime;
            UH--;
            scRotation += "Pugnacity used\n";
        }
        if(SRMP_time <=3){
            //cast SRMP
            SRMP_count++;
            SRMP_cast_count++;
            SRMP_time = 18;
            SRMP_last_tick = eTime;
            tTime = SRMP.getCastTime(speed);
            tEnergy = SRMP.getAmmo();
            ability = "SRMP";
            abil = SRMP;
        }else{
            if(UH==2){
                //cast EMP
                tHeal = EMP.getHealing(bonusHealing)*EMP_buff;
                tTime = EMP.getCastTime(speed);
                tEnergy = EMP.getAmmo();
                ability = "EMP";
                abil = EMP;
                EMP_count++;
                UH--;
            }else{
                if(SRMP_count < 2){
                    //cast SRMP
                    SRMP_count++;
                    SRMP_time = 18;
                    SRMP_last_tick = eTime;
                    tTime = SRMP.getCastTime(speed);
                    tEnergy = SRMP.getAmmo();
                    ability = "SRMP";
                    abil = SRMP;
                    SRMP_cast_count++;
                }else{

                    if(Energy>=(UWM_limit+(UWM.getAmmo()-getEnergyRegened(Energy, UWM, speed)))){
                        //cast UWM
                        tHeal = UWM.getHealing(bonusHealing);
                        tTime = UWM.getCastTime(speed);
                        tEnergy = UWM.getAmmo();
                        ability = "UWM";
                        abil = UWM;
                        UH++;
                        UH_duration=10;
                        UWM_count++;
                        tHeal*= (1+0.1*(ui->skillBox_4->value()));
                    }else{
                        //cast DS
                        //call proc 3 times, compare to crit chance+24. On crit, Energy+=2;
                        tHeal = DS.getHealing(bonusHealing);
                        tTime = DS.getCastTime(speed);
                        tEnergy = DS.getAmmo();
                        ability = "DS";
                        abil = DS;
                        DS_count++;
                        for (int m =0;m<3;m++){
                            proc = Proc(critChance*100+24);
                            if(proc==true)Energy+=2;
                        }
                    }
                }

            }
        }
        //Factor in Critical and Surge to the average heal size
        if(ability=="UWM"){
            tHeal = tHeal * ((1 - critChance / 100)+(1+0.1*(ui->skillBox_4->value()) + critSize / 100)*(critChance / 100));
        }else{
            tHeal = tHeal * ((1 - critChance / 100)+(1 + critSize / 100)*(critChance / 100));
        }
        if(UH>0){tHeal*=1.09;}
        else {tHeal*=1.03;}
        tHeal *=knight_buff;
        eHeal += tHeal;
        UH = max(min(UH, 2),0);
        if(ability == "UWM"){
            scRotation+="UWM , ";}
        if(ability == "EMP")
            scRotation+="EMP , ";
        if(ability == "DS")
            scRotation+="DS , ";
        if(ability == "SRMP")
            scRotation+="SRMP , ";
        //scRotation +=  QString::number(Energy) + " , "+ QString::number(tEnergy) + " , "+ QString::number(rEnergy) + " , " +QString::number(UH) +"\n";
        scRotation +=  QString::number(Energy) + " , "+ QString::number(tHeal) + " , "+ QString::number(eTime) + " , " +QString::number(UH) +"\n";
        SRMP_count = max(min(SRMP_count,2.0),0.0);
        tHeal = 0;
        if(SRMP_time>0 &&(eTime-SRMP_last_tick>=3)){
            tHeal = SRMP_count*SRMP.getHealing(bonusHealing)*hot_buff;
            SRMP_last_tick += 3.0;
            if(SRMP_ICD == 0){
                proc = Proc(30.0);
                if(proc==true){
                    UH++;
                    UH_duration=10.0;
                    SRMP_ICD = 6.0;
                    UH = max(min(UH, 2),0);
                    scRotation += "SRMP UH Proc\n";
                }
            }
            scRotation += "SRMP tick, -- , "+ QString::number(tHeal) + " , " + QString::number(SRMP_last_tick) + " , "  +QString::number(UH) +"\n";
        }
        if(UH>0){tHeal*=1.09;}
        else {tHeal*=1.03;}
        tHeal *=knight_buff;
        eHeal += tHeal;
        eTime += tTime;

        rEnergy = getEnergyRegened(Energy, abil, eTime, regenTime, pugTime, pugRemaining);
        Energy -= (tEnergy - rEnergy);
        Energy = max(min(Energy, 100.0),0.0);

        CH_CD -=tTime;
        SRMP_ICD -= tTime;

        UH_duration -= tTime;
        UH_duration = max(UH_duration, 0.0);
        if(UH_duration == 0)UH = 0;
        SRMP_time -= tTime;
        SRMP_time = max(SRMP_time, 0.0);
        if(SRMP_time == 0)SRMP_count = 0;
        CH_CD = max(CH_CD, 0.0);
        SRMP_ICD = max(SRMP_ICD, 0.0);

        tTime = 0;
        tHeal = 0;
        //scRotation += "SRMP count, " + QString::number(SRMP_count) + " ,time "+ QString::number(SRMP_time) + " , ICD  , " +QString::number(SRMP_ICD) +"\n";
    }
    return eHeal/eTime;
}

double Scoundrel::sawbonesRotation(double rotationTime, vector <double> &stats){
    UWM_count = 0;
    EMP_count = 0;
    SRMP_cast_count = 0;
    DS_count = 0;

    scRotation = "";
    //Abilities
    //Sc: UWM -> EMP (Kolto Injection -> Surgical Probe)
    //Underworld Medicine
    Ability UWM(2.0, 25, false, 2.72, 0.116, 0.156);
    //Emergency Med Probe
    Ability EMP(1.5, 0, true, 1.37, 0.038, 0.098);
    //SRMP (kolto probe)
    Ability SRMP(1.5, 15, true, 0.336, 0.0168, 0.0168, 1, 0.0);//ticks set to one, as each tick will be added on its own.
    //Diagnostic Scan
    Ability DS(3,0,false,0.334,0,0,3,0.0);
    //Pugnacity (Stim Boost) consumes 1 UH/TA but needs to be kept up
    //consumes 1 UH, lasts 45s, adds 1 Energy per second
    //Cool Head (Adrenaline Probe) used if energy drops below 20.
    //restore 50 + 8 per skill point.

    double bonusHealing = stats.at(TECH_BONUS_HEALING);
    double critChance = stats.at(TECH_CRIT_CHANCE);
    double critSize = stats.at(TECH_CRIT_SIZE);
    double speed = stats.at(SPEED);

    double knight_buff = 1;
    if (ui->knightCheckBox->isChecked()) knight_buff = 1.05;
    knight_buff *= (1+0.01*(ui->skillBox_9->value())); //add Survivor's Scars into the healing multiplier.
    //Establish cooldowns and timers
    //UH stacks
    double hot_buff = 1+0.05*(ui->skillBox_5->value());
    double EMP_buff = 1+0.03*(ui->skillBox_5->value());
    double CH_use = ui->optionBox_3->value();
    double pug_use = 2; //create an option for this?
    double Energy = 100;
    int UH = 0;
    double UH_duration = 0; //lasts 10 seconds
    double CH_CD = 0; //2 minute cooldown
    double CH_CD_duration = 120;
    int CH_restore = 50+8*(ui->skillBox_7->value()); //amount Cool Head restore, including Keep Cool skill
    double pugRemaining = 0; //time left on pugnacity
    double pugTime = 0;
    regenTime = 0;
    double SRMP_ICD = 9 - (1.5*(ui->skillBox_8->value()-1)); // how often SRMP can grant UH
    double SRMP_time = 0;
    double SRMP_count = 0;
    double SRMP_last_tick = 0;
    double UWM_limit = ui->optionBox_1->value();
    //SRMP UH proc chance: 30%
    double tTime = 0;
    double tHeal = 0;
    double eTime = 0;
    double eHeal = 0;
    double rEnergy = 0;
    double tEnergy = 0;
    Ability abil;
    string ability;
    bool proc;

    //Opener
    //UWM
    tHeal = UWM.getHealing(bonusHealing)*knight_buff*1.03;
    tHeal = tHeal * ((1 - critChance / 100)+(1+0.1*(ui->skillBox_4->value()) + critSize / 100)*(critChance / 100));
    tTime = UWM.getCastTime(speed);
    tEnergy = UWM.getAmmo();
    ability = "UWM";
    abil = UWM;
    UWM_count++;
    eHeal += tHeal;
    eTime += tTime;
    rEnergy = getEnergyRegened(Energy, abil, eTime, regenTime, pugTime, pugRemaining);
    Energy -= (tEnergy - rEnergy);
    Energy = max(min(Energy, 100.0),0.0);
    UH++;
    UH_duration=10;
    scRotation += "UWM, " + QString::number(Energy) + " , "+ QString::number(tHeal) + " , "+ QString::number(eTime) + " , " +QString::number(UH) +"\n";
    tHeal = 0;
    //pug
    pugRemaining = 45;
    pugTime = eTime;
    UH--;
    scRotation += "Pugnacity used\n";
    //UWM
    tHeal = UWM.getHealing(bonusHealing)*knight_buff*1.03;
    tHeal = tHeal * ((1 - critChance / 100)+(1+0.1*(ui->skillBox_4->value()) + critSize / 100)*(critChance / 100));
    tTime = UWM.getCastTime(speed);
    tEnergy = UWM.getAmmo();
    ability = "UWM";
    abil = UWM;
    UWM_count++;
    eHeal += tHeal;
    eTime += tTime;
    rEnergy = getEnergyRegened(Energy, abil, eTime, regenTime, pugTime, pugRemaining);
    Energy -= (tEnergy - rEnergy);
    Energy = max(min(Energy, 100.0),0.0);
    UH++;
    UH_duration=10;
    scRotation += "UWM, " + QString::number(Energy) + " , "+ QString::number(tHeal) + " , "+ QString::number(eTime) + " , " +QString::number(UH) +"\n";
    tHeal = 0;
    //start loop
    while(eTime < rotationTime){
        if((Energy<=CH_use) && (CH_CD == 0)){
            Energy += CH_restore;
            CH_CD = CH_CD_duration;
        }
        if((pugRemaining<=1.5) && (UH>(pug_use-1)))
        {
            pugRemaining = 45;
            pugTime = eTime;
            UH--;
            scRotation += "Pugnacity used\n";
        }
        if(SRMP_time <=3){
            //cast SRMP
            SRMP_count++;
            SRMP_cast_count++;
            SRMP_time = 18;
            SRMP_last_tick = eTime;
            tTime = SRMP.getCastTime(speed);
            tEnergy = SRMP.getAmmo();
            ability = "SRMP";
            abil = SRMP;
        }else{
            if(UH==2){
                //cast EMP
                tHeal = EMP.getHealing(bonusHealing)*EMP_buff;
                tTime = EMP.getCastTime(speed);
                tEnergy = EMP.getAmmo();
                ability = "EMP";
                abil = EMP;
                EMP_count++;
                UH--;
            }else{
                if(SRMP_count < 2){
                    //cast SRMP
                    SRMP_count++;
                    SRMP_time = 18;
                    SRMP_last_tick = eTime;
                    tTime = SRMP.getCastTime(speed);
                    tEnergy = SRMP.getAmmo();
                    ability = "SRMP";
                    abil = SRMP;
                    SRMP_cast_count++;
                }else{

                    if(Energy>=(UWM_limit+(UWM.getAmmo()-getEnergyRegened(Energy, UWM, speed)))){
                        //cast UWM
                        tHeal = UWM.getHealing(bonusHealing);
                        tTime = UWM.getCastTime(speed);
                        tEnergy = UWM.getAmmo();
                        ability = "UWM";
                        abil = UWM;
                        UH++;
                        UH_duration=10;
                        UWM_count++;
                        tHeal*= (1+0.1*(ui->skillBox_4->value()));
                    }else{
                        //cast DS
                        //call proc 3 times, compare to crit chance+24. On crit, Energy+=2;
                        tHeal = DS.getHealing(bonusHealing);
                        tTime = DS.getCastTime(speed);
                        tEnergy = DS.getAmmo();
                        ability = "DS";
                        abil = DS;
                        DS_count++;
                        for (int m =0;m<3;m++){
                            proc = Proc(critChance*100+24);
                            if(proc==true)Energy+=2;
                        }
                    }
                }

            }
        }
        //Factor in Critical and Surge to the average heal size
        if(ability=="UWM"){
            tHeal = tHeal * ((1 - critChance / 100)+(1+0.1*(ui->skillBox_4->value()) + critSize / 100)*(critChance / 100));
        }else{
            tHeal = tHeal * ((1 - critChance / 100)+(1 + critSize / 100)*(critChance / 100));
        }
        if(UH>0){tHeal*=1.09;}
        else {tHeal*=1.03;}
        tHeal *=knight_buff;
        eHeal += tHeal;
        UH = max(min(UH, 2),0);
        if(ability == "UWM"){
            scRotation+="UWM , ";}
        if(ability == "EMP")
            scRotation+="EMP , ";
        if(ability == "DS")
            scRotation+="DS , ";
        if(ability == "SRMP")
            scRotation+="SRMP , ";
        //scRotation +=  QString::number(Energy) + " , "+ QString::number(tEnergy) + " , "+ QString::number(rEnergy) + " , " +QString::number(UH) +"\n";
        scRotation +=  QString::number(Energy) + " , "+ QString::number(tHeal) + " , "+ QString::number(eTime) + " , " +QString::number(UH) +"\n";
        SRMP_count = max(min(SRMP_count,2.0),0.0);
        tHeal = 0;
        if(SRMP_time>0 &&(eTime-SRMP_last_tick>=3)){
            tHeal = SRMP_count*SRMP.getHealing(bonusHealing)*hot_buff;
            SRMP_last_tick += 3.0;
            if(SRMP_ICD == 0){
                proc = Proc(30.0);
                if(proc==true){
                    UH++;
                    UH_duration=10.0;
                    SRMP_ICD = 6.0;
                    UH = max(min(UH, 2),0);
                    scRotation += "SRMP UH Proc\n";
                }
            }
            scRotation += "SRMP tick, -- , "+ QString::number(tHeal) + " , " + QString::number(SRMP_last_tick) + " , "  +QString::number(UH) +"\n";
        }
        if(UH>0){tHeal*=1.09;}
        else {tHeal*=1.03;}
        tHeal *=knight_buff;
        eHeal += tHeal;
        eTime += tTime;

        rEnergy = getEnergyRegened(Energy, abil, eTime, regenTime, pugTime, pugRemaining);

        Energy -= (tEnergy - rEnergy);
        Energy = max(min(Energy, 100.0),0.0);

        CH_CD -=tTime;
        SRMP_ICD -= tTime;

        UH_duration -= tTime;
        UH_duration = max(UH_duration, 0.0);
        if(UH_duration == 0)UH = 0;
        SRMP_time -= tTime;
        SRMP_time = max(SRMP_time, 0.0);
        if(SRMP_time == 0)SRMP_count = 0;
        CH_CD = max(CH_CD, 0.0);
        SRMP_ICD = max(SRMP_ICD, 0.0);

        tTime = 0;
        tHeal = 0;
        //scRotation += "SRMP count, " + QString::number(SRMP_count) + " ,time "+ QString::number(SRMP_time) + " , ICD  , " +QString::number(SRMP_ICD) +"\n";
    }
    return eHeal/eTime;
}

double Scoundrel::sawbonesBurst(double rotationTime, vector <double> &stats){
    UWM_count = 0;
    EMP_count = 0;
    KPa_count = 0;
    DS_count = 0;
    SRMP_cast_count = 0;

    double KPa_crit_bonus = 0;
    if(ui->check4pcBox->isChecked()){KPa_crit_bonus = 0.15;}
    scRotation.clear();
    //Underworld Medicine
    Ability UWM(2.0, 25, false, 2.72, 0.116, 0.156);
    //Emergency Med Probe
    Ability EMP(1.5, 0, true, 1.37, 0.038, 0.098);
    //Kolto Pack
    Ability KPa(1.5, 20, false, 2.37, 0.098, 0.138);
    //SRMP (kolto probe)
    Ability SRMP(1.5, 15, true, 0.336, 0.0168, 0.0168, 1, 0.0);//ticks set to one, as each tick will be added on its own.
    //Diagnostic Scan
    Ability DS(3,0,false,0.334,0,0,3,0.0);

    double techBonusHealing = stats.at(TECH_BONUS_HEALING);
    double techCritChance = stats.at(TECH_CRIT_CHANCE);
    double techCritSize = stats.at(TECH_CRIT_SIZE);
    double speed = stats.at(SPEED);

    double knight_buff = 1;
    if (ui->knightCheckBox->isChecked()) knight_buff = 1.05;
    knight_buff *= (1+0.01*(ui->skillBox_9->value())); //add Survivor's Scars into the healing multiplier.
    //Establish cooldowns and timers
    //UH stacks
    double hot_buff = 1+0.05*(ui->skillBox_5->value());
    double EMP_buff = 1+0.03*(ui->skillBox_5->value());
    double CH_use = ui->optionBox_3->value();
    double pug_use = 2; //create an option for this?
    double Energy = 100;
    int UH = 2;
    double UH_duration = 0; //lasts 10 seconds
    double CH_CD = 0; //2 minute cooldown
    double CH_CD_duration = 120;
    int CH_restore = 50+8*(ui->skillBox_7->value()); //amount Cool Head restore, including Keep Cool skill
    double pugRemaining = 45; //time left on pugnacity
    double pugTime = 0;
    regenTime = 0;
    double SRMP_ICD = 9 - (1.5*(ui->skillBox_8->value()-1)); // how often SRMP can grant UH
    double SRMP_time = 16.5;
    double SRMP_count = 2;
    double SRMP_last_tick = 0;
    double UWM_limit = ui->optionBox_1->value();
    //SRMP UH proc chance: 30%
    double tTime = 0;
    double tHeal = 0;
    double eTime = 0;
    double eHeal = 0;
    double rEnergy = 0;
    double tEnergy = 0;
    Ability abil;
    string ability;
    bool proc;

    while(eTime < rotationTime){
        if((Energy<=CH_use) && (CH_CD == 0)){
            Energy += CH_restore;
            CH_CD = CH_CD_duration;
        }
        if((pugRemaining<=1.5) && (UH>(pug_use-1)))
        {
            pugRemaining = 45;
            pugTime = eTime;
            UH--;
            scRotation += "Pugnacity used\n";
        }
        if(SRMP_time <=3){
            //cast SRMP
            SRMP_count++;
            SRMP_cast_count++;
            SRMP_time = 18;
            SRMP_last_tick = eTime;
            tTime = SRMP.getCastTime(speed);
            tEnergy = SRMP.getAmmo();
            ability = "SRMP";
            abil = SRMP;
        }else{
            if(UH==2){
                //cast KPa
                tHeal = KPa.getHealing(techBonusHealing);
                tTime = KPa.getCastTime(speed);
                tEnergy = KPa.getAmmo();
                ability = "KPa";
                abil = KPa;
                KPa_count++;
                UH--;
            }else{if(Energy>=(UWM_limit+(UWM.getAmmo()-getEnergyRegened(Energy, UWM, speed)))){
                    //cast UWM
                    tHeal = UWM.getHealing(techBonusHealing);
                    tTime = UWM.getCastTime(speed);
                    tEnergy = UWM.getAmmo();
                    ability = "UWM";
                    abil = UWM;
                    UH++;
                    UH_duration=10;
                    UWM_count++;
                    tHeal*= (1+0.1*(ui->skillBox_4->value()));
                }else{
                    //cast DS
                    //call proc 3 times, compare to crit chance+24. On crit, Energy+=2;
                    tHeal = DS.getHealing(techBonusHealing);
                    tTime = DS.getCastTime(speed);
                    tEnergy = DS.getAmmo();
                    ability = "DS";
                    abil = DS;
                    DS_count++;
                    for (int m =0;m<3;m++){
                        proc = Proc(techCritChance*100+24);
                        if(proc==true)Energy+=2;
                    }
                }

            }
        }
        //Factor in Critical and Surge to the average heal size
        if(ability=="UWM"){
            tHeal = tHeal * ((1 - techCritChance / 100)+(1+0.1*(ui->skillBox_4->value()) + techCritSize / 100)*(techCritChance / 100));
        }else{
            if(ability=="KPa"){
                tHeal = tHeal * ((1 - ((techCritChance / 100)+KPa_crit_bonus))+(1 + techCritSize / 100)*((techCritChance / 100)+KPa_crit_bonus));
            }else{
                tHeal = tHeal * ((1 - techCritChance / 100)+(1 + techCritSize / 100)*(techCritChance / 100));
            }
        }

        if(UH>0){tHeal*=1.09;}
        else {tHeal*=1.03;}
        tHeal *=knight_buff;
        eHeal += tHeal;
        UH = max(min(UH, 2),0);
        if(ability == "UWM"){
            scRotation+="UWM , ";}
        if(ability == "KPa")
            scRotation+="KPa , ";
        if(ability == "DS")
            scRotation+="DS , ";
        if(ability == "SRMP")
            scRotation+="SRMP , ";
        scRotation +=  QString::number(Energy) + " , "+ QString::number(tHeal) + " , "+ QString::number(eTime) + " , " +QString::number(UH) +"\n";
        SRMP_count = max(min(SRMP_count,2.0),0.0);
        tHeal = 0;
        if(SRMP_time>0 &&(eTime-SRMP_last_tick>=3)){
            tHeal = SRMP_count*SRMP.getHealing(techBonusHealing)*hot_buff;
            SRMP_last_tick += 3.0;
            if(SRMP_ICD == 0){
                proc = Proc(30.0);
                if(proc==true){
                    UH++;
                    UH_duration=10.0;
                    SRMP_ICD = 6.0;
                    UH = max(min(UH, 2),0);
                    scRotation += "SRMP UH Proc\n";
                }
            }
            scRotation += "SRMP tick, -- , "+ QString::number(tHeal) + " , " + QString::number(SRMP_last_tick) + " , "  +QString::number(UH) +"\n";
        }
        if(UH>0){tHeal*=1.09;}
        else {tHeal*=1.03;}
        tHeal *=knight_buff;
        eHeal += tHeal;
        eTime += tTime;

        rEnergy = getEnergyRegened(Energy, abil, eTime, regenTime, pugTime, pugRemaining);

        Energy -= (tEnergy - rEnergy);
        Energy = max(min(Energy, 100.0),0.0);

        CH_CD -=tTime;
        SRMP_ICD -= tTime;

        UH_duration -= tTime;
        UH_duration = max(UH_duration, 0.0);
        if(UH_duration == 0)UH = 0;
        SRMP_time -= tTime;
        SRMP_time = max(SRMP_time, 0.0);
        if(SRMP_time == 0)SRMP_count = 0;
        CH_CD = max(CH_CD, 0.0);
        SRMP_ICD = max(SRMP_ICD, 0.0);

        tTime = 0;
        tHeal = 0;
    }
    return eHeal/eTime;
}

void Scoundrel::on_levelBox_editingFinished()
{
    updateStatBoxes();
}

void Scoundrel::on_primaryBox_editingFinished()
{
    updateStatBoxes();
}

void Scoundrel::on_powerBox_editingFinished()
{
    updateStatBoxes();
}

void Scoundrel::on_techBox_editingFinished()
{
    updateStatBoxes();
}

void Scoundrel::on_critBox_editingFinished()
{
    updateStatBoxes();
}

void Scoundrel::on_surgeBox_editingFinished()
{
    updateStatBoxes();
}

void Scoundrel::on_alacBox_editingFinished()
{
    updateStatBoxes();
}

void Scoundrel::on_accBox_editingFinished()
{
    updateStatBoxes();
}

void Scoundrel::on_MHmaxBox_editingFinished()
{
    updateStatBoxes();
}

void Scoundrel::on_MHminBox_editingFinished()
{
    updateStatBoxes();
}

void Scoundrel::on_enemyLevelBox_editingFinished()
{
    updateStatBoxes();
}

void Scoundrel::on_enemyArmorBox_editingFinished()
{
    updateStatBoxes();
}

void Scoundrel::on_skillBox_1_editingFinished()
{
    updateStatBoxes();
}

void Scoundrel::on_skillBox_2_editingFinished()
{
    updateStatBoxes();
}

void Scoundrel::on_skillBox_4_editingFinished()
{
    updateStatBoxes();
}

void Scoundrel::on_skillBox_5_editingFinished()
{
    updateStatBoxes();
}

void Scoundrel::on_skillBox_6_editingFinished()
{
    updateStatBoxes();
}

void Scoundrel::on_skillBox_7_editingFinished()
{
    updateStatBoxes();
}

void Scoundrel::on_skillBox_8_editingFinished()
{
    updateStatBoxes();
}

void Scoundrel::on_skillBox_9_editingFinished()
{
    updateStatBoxes();
}

void Scoundrel::on_consularCheckBox_clicked()
{
    updateStatBoxes();
}

void Scoundrel::on_smugglerCheckBox_clicked()
{
    updateStatBoxes();
}

void Scoundrel::on_knightCheckBox_clicked()
{
    updateStatBoxes();
}

void Scoundrel::on_check2pcBox_toggled(bool checked)
{
    if(checked==false) ui->check4pcBox->setChecked(false);
}

void Scoundrel::on_check4pcBox_toggled(bool checked)
{
    if(checked==true) ui->check2pcBox->setChecked(true);
}

void Scoundrel::on_OHmaxBox_editingFinished()
{
    updateStatBoxes();
}

void Scoundrel::on_OHminBox_editingFinished()
{
    updateStatBoxes();
}

void Scoundrel::on_note1_clicked()
{
    ui->countView->clear();
    QString note1 = "*Note 1: Alacrity has no effect on instant cast abilities or HoTs, such as EMP and SRMP.\n\n";
    note1 += "For UWM, it casts faster, but the tradeoff is less regen while casting, which raises the Effective Cost and reduces your ability to cast it as often before running out of Energy.\n\n";
    note1 += "As alacrity increases, DS will make up a larger and larger percentage of your casts, reducing how well you scale when adding other upgrades.\n\n";
    note1+= "Note that these limits become less of a concern as you overgear your encounters and you increase your downtime. That turns the encounter from a sustained healing to a burst healing mode with recovery times, and the increased Effective Cost is less problematic. Use your best judgment.\n\n";
    note1 += "For more information and my analysis of alacrity's value for Operatives/Scoundrels, see this thread on the SWTOR forums:\n\nhttp://www.swtor.com/community/showthread.php?t=309664";
    ui->countView->insertPlainText(note1);
    updateStatBoxes();
}


void Scoundrel::on_saveStats_clicked()
{
    setStats();
    string filename = "Scoundrel_stats.txt";
    ofstream fout (filename.c_str());
    fout << scStats.at(CUNNING) << "\n" << scStats.at(AIM) << "\n" << scStats.at(CRIT)<< "\n" <<
            scStats.at(SURGE) << "\n" << ui->powerBox->value() << "\n" << ui->techBox->value() << "\n" << scStats.at(ALACRITY) << "\n" <<
            scStats.at(LEVEL) << "\n" << scStats.at(ACCURACY) << "\n" << scStats.at(MH_MAX) << "\n" <<
            scStats.at(MH_MIN) << "\n" << scStats.at(ENEMY_LEVEL) << "\n" << scStats.at(ENEMY_ARMOR) << endl;

    fout << ui->skillBox_1->value() << "\n" << ui->skillBox_2->value() << "\n" << 0 << "\n" <<
            ui->skillBox_4->value() << "\n" << ui->skillBox_5->value() << "\n" << ui->skillBox_6->value() << "\n" <<
            ui->skillBox_7->value() << "\n" << ui->skillBox_8->value() << "\n" << ui->skillBox_9->value() <<  endl;

    fout << scStats.at(OH_MAX) << "\n" << scStats.at(OH_MIN) << endl;
    fout.close();
}

void Scoundrel::on_loadStats_clicked()
{
    Load_Stats();
}

void Scoundrel::Load_Stats(){
    string filename = "Scoundrel_stats.txt";
    ifstream fin (filename.c_str());
    vector <string> inputStats(27,"0");
    int i=0;
    while(fin.good()){
        getline(fin,inputStats.at(i));
        i++;
    }
    ui->primaryBox->setValue(atoi(inputStats.at(0).c_str()));
    //ui->secondaryBox->setValue(atoi(inputStats.at(1).c_str()));
    ui->critBox->setValue(atoi(inputStats.at(2).c_str()));
    ui->surgeBox->setValue(atoi(inputStats.at(3).c_str()));
    ui->powerBox->setValue(atoi(inputStats.at(4).c_str()));
    ui->techBox->setValue(atoi(inputStats.at(5).c_str()));
    ui->alacBox->setValue(atoi(inputStats.at(6).c_str()));
    ui->levelBox->setValue(atoi(inputStats.at(7).c_str()));
    ui->accBox->setValue(atoi(inputStats.at(8).c_str()));
    ui->MHmaxBox->setValue(atoi(inputStats.at(9).c_str()));
    ui->MHminBox->setValue(atoi(inputStats.at(10).c_str()));
    ui->enemyLevelBox->setValue(atoi(inputStats.at(11).c_str()));
    ui->enemyArmorBox->setValue(atoi(inputStats.at(12).c_str()));

    //set skill boxes
    ui->skillBox_1->setValue(atoi(inputStats.at(13).c_str()));
    ui->skillBox_2->setValue(atoi(inputStats.at(14).c_str()));
    //ui->skillBox_3->setValue(atoi(inputStats.at(15).c_str()));
    ui->skillBox_4->setValue(atoi(inputStats.at(16).c_str()));
    ui->skillBox_5->setValue(atoi(inputStats.at(17).c_str()));
    ui->skillBox_6->setValue(atoi(inputStats.at(18).c_str()));
    ui->skillBox_7->setValue(atoi(inputStats.at(19).c_str()));
    ui->skillBox_8->setValue(atoi(inputStats.at(20).c_str()));
    ui->skillBox_9->setValue(atoi(inputStats.at(21).c_str()));

    //Off-hand stats
    ui->OHmaxBox->setValue(atoi(inputStats.at(22).c_str()));
    ui->OHminBox->setValue(atoi(inputStats.at(23).c_str()));
    fin.close();
}

void Scoundrel::on_tree1_clicked()
{
    updateStatBoxes();
}

void Scoundrel::on_tree2_clicked()
{
    updateStatBoxes();
}

void Scoundrel::on_tree3_clicked()
{
    updateStatBoxes();
}

void Scoundrel::on_note2_clicked()
{
    ui->countView->clear();
    QString note1 = "Note 2: Due to the random nature (RNG) of the Upper Hand generation by Slow-Release Medpac and the random energy return on crit component of Diagnostic Scan, multiple runs should be averaged to smooth out randomness.  The more runs, the longer it will take. Currently this field has a range of 1-10000 runs.";
    note1 += "\n\nThe output windows will only display the results of the last rotation, as an example set of how the rotation looked for a given set of RNG values.";
    note1 += "\n\nBe careful setting this value too high, as it will cause the Stat Weight and Upgrade Calculator buttons to take a long time to process.  The Stat Weight button requires 7* this value of rotations to work, so setting it to 10000 will require 70000 simulated rotations.";
    note1 += "\n\nTo remove variability in the outputs and allow proper comparison, the same RNG seed is fed to both rotations at the start.  This makes them the same on display to you, but internally they vary each time.";
    ui->countView->insertPlainText(note1);
    updateStatBoxes();
}


void Scoundrel::on_sustainedButton_clicked()
{
    ui->fixedCastButton->setEnabled(true);
    ui->numCasts->setMaximum(3000.00);
    ui->numCasts->setValue(300.00);

    ui->optionBox_1->setValue(60);
}

void Scoundrel::on_burstButton_clicked()
{
    ui->fixedCastButton->setEnabled(false);
    ui->fixedTimeButton->setChecked(true);
    ui->numCasts->setMaximum(30.00);
    ui->numCasts->setValue(30.00);
    ui->optionBox_1->setValue(20);
}
